以windows服务的方式运行NuGet Server

momo314相同方式共享非商业用途署名转载

从.NET Framework到.NETCore的演变来看,NuGet的使用在.NET平台技术栈里应该是一个大趋势。作为一个有追求的.NET开发者,我觉得,怎么着都应该有一个自己的 Private NuGet Server 吧。出道这么多年,谁还没几把趁手的兵器不是,总有些东西是我们不想直接扔到公共仓库里的。

怎么搭建自己的 NuGet Server 呢,这个网上大把文章都已经说烂了,也很简单,不再多说。总之,按照网上的教程,我们已经得到了一个WebApi版本的NuGet Server,现在只需要把他扔到IIS里面,这事儿就算是成了。

但是我觉得不太好,为啥呢?

毕竟现在已经进入 .NET Core 的时代了,大家都想玩玩 .NET Core,也都想尝试着玩一下 .NET Core 跨平台。那为了减少本地和线上环境的差异,减少上线时幺蛾子出现的几率,所以我本地也特意安装了 Nginx 来跑 .NET Core 程序。

那么问题就来了,大家都知道 IIS 和 Nginx 都会默认使用 80 端口,会有冲突;而且 IIS 虽然简单好用,但相比 Nginx 确实是有点重了。所以,我个人的选择是,放弃IIS,尽量使用Nginx。

可是,没有了IIS,我们怎么来运行 NuGet Server WebApi 项目呢?毕竟到现在为止,NuGet 还没有为我们提供 .NET Core 版本的 Server 包。

还好,我还知道另一种办法 ╰(°▽°)╯

我们还可以使用控制台程序以自托管的方式运行 WebApi 程序,具体可以参见 脱离IIS,.NET WebApi的自托管(Self-Hosting)之路

一、 NuGet Server 自托管改造过程:

  1. 新建 控制台应用(.NET Framwework)
  2. 从 NuGet 添加以下引用
    • Microsoft.AspNet.WebApi
    • NuGet.Server.V2
    • NuGet.Server
    • Microsoft.AspNet.WebApi.SelfHost
  3. 删除 App_Start 文件夹
  4. 修改配置文件,添加配置项
    <appSettings>
     <!--监听端口号-->
     <add key="port" value="8000"/>
    </appSettings>
    
  5. 修改配置文件,添加如下配置节点
    <system.web>
     <compilation debug="true" targetFramework="4.6.1" />
     <!-- maxRequestLength is specified in Kb -->
     <httpRuntime targetFramework="4.6.1" maxRequestLength="102400" />
    </system.web>
    <system.webServer>
     <handlers>
       <remove name="WebDAV" />
       <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
       <remove name="OPTIONSVerbHandler" />
       <remove name="TRACEVerbHandler" />
       <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
     </handlers>
     <staticContent>
       <mimeMap fileExtension=".nupkg" mimeType="application/zip" />
     </staticContent>
     <modules runAllManagedModulesForAllRequests="true">
       <remove name="WebDAVModule" />
     </modules>
     <security>
       <requestFiltering>
         <!-- maxAllowedContentLength is specified in Bytes -->
         <requestLimits maxAllowedContentLength="31457280" />
       </requestFiltering>
     </security>
    </system.webServer>
    <system.serviceModel>
     <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    </system.serviceModel>
    
  6. 修改入口程序类Program.cs,如下:

    using NuGet.Server;
    using NuGet.Server.Infrastructure;
    using NuGet.Server.V2;
    using System;
    using System.Configuration;
    using System.Net.Http;
    using System.Web.Http;
    using System.Web.Http.ExceptionHandling;
    using System.Web.Http.Routing;
    using System.Web.Http.SelfHost;
    
    [assembly: WebActivatorEx.PreApplicationStartMethod(typeof(NuGet.PrivateServer.Program), "Start")]
    namespace NuGet.PrivateServer
    {
       class Program
       {
           private static HttpSelfHostConfiguration _config;
    
           static void Main(string[] args)
           {
    
               var port = ConfigurationManager.AppSettings["port"];
               Initialize(port);
    
               using (HttpSelfHostServer server = new HttpSelfHostServer(_config))
               {
                   server.OpenAsync().Wait();
                   Console.WriteLine($"server listening {port}...");
                   Console.WriteLine("press any key to quit.");
                   Console.ReadLine();
               }
           }
    
           private static void Initialize(string port)
           {
               ServiceResolver.SetServiceResolver(new DefaultServiceResolver());
    
               _config = new HttpSelfHostConfiguration($"http://localhost:{port}");
    
               NuGetV2WebApiEnabler.UseNuGetV2WebApiFeed(_config, "NuGetDefault", "nuget", "PackagesOData");
    
               _config.Services.Replace(typeof(IExceptionLogger), new TraceExceptionLogger());
    
               // Trace.Listeners.Add(new TextWriterTraceListener(HostingEnvironment.MapPath("~/NuGet.Server.log")));
               // Trace.AutoFlush = true;
    
               _config.Routes.MapHttpRoute(
                   name: "NuGetDefault_ClearCache",
                   routeTemplate: "nuget/clear-cache",
                   defaults: new { controller = "PackagesOData", action = "ClearCache" },
                   constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) }
               );
    
               _config.Routes.MapHttpRoute(
                   "API Default",
                   "api/{controller}/{id}",
                   new { id = RouteParameter.Optional });
           }
       }
    }
    
  7. 点击运行,检测 NuGet Server 自托管 webapi 是否可用

二、 将 NuGet Server 配置成 windows 服务,以便实现开机启动

我们将通过 NSSM 将刚刚做好的 NuGet Self Hosting Server 制作成 windows服务,关于 NSSM 的更多信息可以查阅:[NSSM使用介绍]。

  1. 使用管理员身份运行cmd
  2. 输入命令:

    nssm install nuget.service
    
    • 执行此命令需要将nssm.exe下的对应目录加入环境变量,否则请先进入对应目录再执行以上命令
    • nuget.service 为windows服务名称
  3. 在弹出的界面中按照要求填写完毕后,点击 Install Service 即可将webapi自托管站点安装为windows服务

也可以用 NSSM 将 Nginx 安装为服务。

三、 在 Nginx 和 hosts文件 中配置相应的本地域名来更方便的访问我们的 NuGet Server

nginx配置:

server {
    listen          80;
    charset         utf-8;
    server_name     nuget.private-server.com;
    location / {
        proxy_pass   http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Connection keep-alive;
    }
}

hosts配置:

127.0.0.1    nuget.private-server.com

附:NuGet Private Self-Hosting Server 源码下载

✎﹏ 本文来自于 momo314和他们家的猫,文章原创,转载请注明作者并保留原文链接。